package newx
{
	import com.cjson.CJSON;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Graphics;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.net.URLRequest;
	import flash.text.TextField;
	
	import newx.com.LayoutType;
	import newx.com.ResManager;
	import newx.com.config.StaticIni;
	import newx.com.control.NxToolTips;
	import newx.com.loader.SwfLoader;
	import newx.utils.BMath;
	import newx.utils.DateFormatter;
	import newx.utils.DrawAPI;
	import newx.utils.KeyCommand;
	import newx.utils.MouseHandle;
	import newx.utils.coders.MD5;
	import newx.utils.debug.DebugWindow;
	import newx.utils.debug.IO;
	
	public class NxApi extends EventDispatcher
	{
		private static var _self		:NxApi;
		
		private var _EngineInited		:Boolean	=	false;
		
		private var _mainAppLoaderInfo	:LoaderInfo;
		
		private var _stage				:Stage;
		
		private var _httpValObj		:Object;
		
		private var _gameVersion		:String;
		
		/**
		 * 背景图源
		 * */
		private var bgBitmapData		:BitmapData;
		
		/**
		 * 背景布局方式
		 * */
		private var _layout			:String;
		
		/**
		 * 主背景层
		 * */
		private var mainBGSpace		:Sprite;
		
		public function NxApi()
		{
			
		}
		
		/**
		 * 记录基本信息 
		 * @param val				主App的LoaderInfo信息
		 * @param valStage			舞台Stage对象
		 * @param valHttpObj		http参数
		 * @param valGameVersion	配置文件读取出的gameVersion
		 * 
		 */
		public function initEngineInfo(
			val				:LoaderInfo,
			valStage		:Stage,
			valHttpObj		:Object,
			valGameVersion	:String):void
		{
			_mainAppLoaderInfo	=	val;
			_stage				=	valStage;
			_httpValObj			=	valHttpObj;
			_gameVersion		=	valGameVersion;
			
			//设置舞台布局=======================================================
			_stage.align		=	StageAlign.TOP_LEFT;
			_stage.scaleMode	=	StageScaleMode.NO_SCALE;
		}
		
		public function clearStage():void
		{
			if(_stage != null)
			{
				while(_stage.numChildren > 0)
				{
					_stage.removeChildAt(0);
				}
				IO.GC();
			}
		}
		
		/**
		 * 
		 * @param bgResUrl
		 * @param layout
		 * 
		 */		
		public function setStageBG(
			bgResUrl	:*		=	null,
			layout		:String = 	null):void
		{
			if(stage != null)
			{
				_layout	=	layout;
				//设置舞台背景============================================================================
				var tLoader:Loader	=	new Loader();
				
				if(bgResUrl != "" && bgResUrl != null)
				{
					mainBGSpace	=	new Sprite();
					stage.addChild(mainBGSpace);
					
					if(bgResUrl is String)
					{
						if(layout == LayoutType.CENTER)
						{
							tLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,
								onImgAddComplete);						
						}
						else if(layout == LayoutType.TILE || layout == null)
						{
							tLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,
								onImgLoadComplete);
						}
						
						tLoader.load(new URLRequest(bgResUrl));
					}
					else
					{
						if(layout == LayoutType.CENTER)
						{
							mainBGSpace.addChild(bgResUrl);
							onImgAddComplete(bgResUrl)
						}
						else if(layout == LayoutType.TILE)
						{
							onImgLoadComplete(bgResUrl)
						}
					}
				}
				
				stage.addEventListener(Event.RESIZE,onStageReSize);
			}
		}
		
		private function onImgLoadComplete(e:Event):void
		{
			//bitmap e.data
			bgBitmapData	=	(e.target.content as Bitmap).bitmapData;
			mainBGSpace.graphics.clear();
			mainBGSpace.graphics.beginBitmapFill(bgBitmapData);
			mainBGSpace.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
			mainBGSpace.graphics.endFill();
		};
		
		private function onImgAddComplete(e:Event):void
		{
			mainBGSpace.addChild(e.target.content);
			mainBGSpace.x	=	(stage.stageWidth	-mainBGSpace.width)*.5
			mainBGSpace.y	=	(stage.stageHeight	-mainBGSpace.height)*.5
		};
		
		
		private function onStageReSize(e:Event):void
		{
			if(_layout == LayoutType.TILE && bgBitmapData != null)
			{
				mainBGSpace.graphics.clear();
				mainBGSpace.graphics.beginBitmapFill(bgBitmapData);
				mainBGSpace.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
				mainBGSpace.graphics.endFill();
			}
			else if(_layout == LayoutType.CENTER && mainBGSpace != null)
			{
				mainBGSpace.x	=(stage.stageWidth	-mainBGSpace.width)*.5
				mainBGSpace.y	=(stage.stageHeight	-mainBGSpace.height)*.5
			}
		}
		
		/**
		 * 获取配置文件中配置的游戏版本字符串
		 * */
		public function get gameVersion():String
		{
			return _gameVersion;
		}

		/**
		 * 网页地址中的http参数
		 * */
		public function get httpValObj():Object
		{
			return _httpValObj;
		}

		/**
		 * 舞台stage对象
		 * */
		public function get stage():Stage
		{
			return _stage;
		}

		static public function get API():NxApi
		{
			if(_self == null)
			{
				_self	=	new NxApi();
			}
			return _self;
		}
		
		/**
		 * 在引擎接口上派发事件
		 * @param eventClassName	：事件类类名
		 * @param type				：事件名
		 * @param data				：参数
		 * 
		 */
		public function DispatchEngineEvent(eventClassName:String,type:String,data:Object = null):void
		{
			var tEventClass:Class	=	_mainAppLoaderInfo.
				applicationDomain.getDefinition(eventClassName) as Class;
			
			this.dispatchEvent(new tEventClass(type,data));
		}
		
		/**
		 * 引擎初始化完毕
		 * */
		public function get EngineInited():Boolean
		{
			return _EngineInited;
		}
		
		public function set EngineInited(val:Boolean):void
		{
			_EngineInited	=	val;
		}
		
		/**
		 * 获取IO接口原型 
		 * @return 
		 * 
		 */		
		public function IO_GetIO():IO
		{
			return IO.io;
		}
		
		//Json======================================================
		/**
		 * 解析 JSON 字符串，将其转化为Object对象。
		 * @param val	：JSON 字符串
		 * @return 		：object 对象
		 * 
		 */	
		public function JSON_Decode(val:String):Object
		{
			return CJSON.decode(val);
		}
		
		/**
		 * 编码 JSON 字符串，将Object数据对象编译成 JSON 字符串
		 * @param val	：object 对象
		 * @return 		： JSON 字符串
		 * 
		 */	
		public function JSON_Encode(val:Object):String
		{
			return CJSON.encode(val);
		}
		
		//config信息管理============================================
		/**
		 * 初始化配置管理器，配置管理器只能且必须初始化后才能被使用
		 * @param objData	配置信息的原始数据，由外部加载而来，也就是外部打包文件
		 * ConfigData 上的数据
		 * 
		 */
		public function Config_Init(objData:Object):void
		{
			StaticIni.initStaticFromObj(objData);
		}
		
		private function Config_GetClass(
			loadinfo	:LoaderInfo,
			classPath	:String):Class
		{
			return StaticIni.getClipClass(loadinfo,classPath);
		}
		
		private function Config_GetStaticInstance(
			loadinfo	:LoaderInfo,
			classPath	:String,
			...argc):Object
		{
			return StaticIni.getClipClass(
				loadinfo,classPath)["getInstance"](argc);
		}
		
		/**
		 * 获取某一配置信息对象 
		 * @param configID	：索引键
		 * @return 
		 * 
		 */
		public function Config_GetObj(configID:String):Object
		{
			return StaticIni.getIniObj(configID);
		}
		
		/**
		 * 获取某一配置信息的某一指定属性
		 * @param configID 	：索引键
		 * @param valKey	：属性名
		 * @return 
		 * 
		 */	
		public function Config_GetObjVar(configID:*, valKey:String):String
		{
			return StaticIni.getIniVar(configID,valKey);
		}
		
		/**
		 * 获取配置好的字符串
		 * @param StrID		：索引键
		 * @return 
		 * 
		 */
		public function Config_GetLangStr(StrID:String):String
		{
			return StaticIni.getSwfLangStr(StrID);
		}
		
		/**
		 * 获取配置好的填充字符串，与普通字符串不同，该字符串允许动态填充一些值，
		 * 这些值可以按顺序记录在参数valArr上，也就是说所有在字符串中标价过的位置（@）
		 * 回按顺序依次由valArr的值填充。
		 * @param StrID		：索引键
		 * @param valArr	：用于填充字符串的参数
		 * @return 
		 * 
		 */
		public function Config_GetLangStrVar(StrID:String,valArr:Array):String
		{
			return StaticIni.getSwfLangStrVar(StrID,valArr);
		}

		//debug=====================================================
		/**
		 * 调试器启用开关 
		 * @return 
		 * 
		 */
		private function get Debug_Enabled():Boolean
		{
			return DebugWindow.enabled;
		}
		
		private function set Debug_Enabled(value:Boolean):void
		{
			DebugWindow.enabled	=	value;
		}
		
		/**
		 * 调试器信息输出开关 
		 * @return 
		 * 
		 */	
		private function get Debug_OutMessage():Boolean
		{
			return DebugWindow.outMessage;
		}
		
		private function set Debug_OutMessage(value:Boolean):void
		{
			DebugWindow.outMessage	=	value;
		}
		
		/**
		 * 调试器命令监听接口 
		 * @param value	监听处理函数，回调参数func(val:String);
		 * 
		 */	
		private function Debug_SetCommandFun(value:Function):void
		{
			DebugWindow.DebugCommandFun	=	value;
		}
		
		//loader(加载器)==============================================
		
		/**
		 * 加载图片或swf资源
		 * @param url				：资源地址
		 * @param beAddContainer	：显示容器（可选，当有值时，自动添加到容器中）
		 * @param complete			：完成处理函数，
		 * 回调参数func(val:DisplayObject，pList:Array);
		 * @param valList			：跟随complete一起传递的参数
		 * 
		 */
		public function Loader_StartLoad(
			url:String,
			beAddContainer:DisplayObjectContainer=null,
			complete:Function=null,
			valList:Array=null):void
		{
			SwfLoader.StartLoad(
				url,beAddContainer,complete,valList);
		}
		
		//DrawApi(绘图接口)============================================
		/**
		 * 清空绘图 
		 * @param value	：绘图对象。
		 * 
		 */
		public function DrawApi_Clear(value:Shape):void
		{
			DrawAPI.clear(value);
		}
		
		/**
		 * 测量某个显示对象的真实大小 ，该接口会遍历所有子对象从而确定真实大小。
		 * @param value	：待测量的显示对象
		 * @return 		：测量结果
		 * 
		 */
		public function DrawApi_GetTrueRect(
			value:DisplayObjectContainer=null):Rectangle
		{
			return DrawAPI.getTrueRect(value);
		}
		
		/**
		 * 获取文本控件的位图镜像。 
		 * @param labelField	：文本控件。
		 * @return 				：位图。
		 * 
		 */
		public function DrawApi_GetLabelBitmap(labelField:TextField):Bitmap
		{
			return DrawAPI.getLabelBitmap(labelField);
		}
		
		/**
		 * 生成指定文本格式的文本位图对象。 
		 * @param str		：文本字符串
		 * @param setObj	：用于设置文本格式，
		 * 这些值将被设置到文本控件TextField上。
		 * @return 			：位图。
		 * 
		 */
		public function DrawApi_GetStringBitmap(
			str:String, setObj:Object=null):Bitmap
		{
			return DrawAPI.getStringBitmap(str,setObj);
		}
		
		/**
		 * 绘制三角形 
		 * @param spriteGraphics	：要绘制的目标对象
		 * @param p1				：三角形的一个顶点
		 * @param p2				：三角形的另一个顶点
		 * @param p3				：三角形的第三个顶点
		 * @param fillStyle			：背景填充类型，该值可由
		 * newx.com.utils.draw.DrawStyle生成。
		 * @param lineStyle			：线条类型，该值可由
		 * newx.com.utils.draw.DrawStyle生成。
		 * @param lineGradientStyle	：线条渐变类型，该值可由
		 * newx.com.utils.draw.DrawStyle生成。
		 * 
		 */
		public function DrawApi_DrawTriAngleBg(
			spriteGraphics:Graphics,
			p1:Point,
			p2:Point,
			p3:Point,
			fillStyle:BaseObject=null,
			lineStyle:BaseObject=null,
			lineGradientStyle:BaseObject=null):void
		{
			DrawAPI.DrawTriAngleBg(
				spriteGraphics,p1,p2,p3,fillStyle,lineStyle,lineGradientStyle);
		}
		
		/**
		 * 绘制由位图填充的图像 
		 * @param spriteGraphics	：待绘制目标。
		 * @param rectStyle			：用于定义矩形样式，可由
		 * newx.com.utils.draw.DrawStyle生成。
		 * @param bmd				：用于填充的位图。
		 * 
		 */
		public function DrawApi_DrawRectWithBitMapFill(
			spriteGraphics:Graphics,
			rectStyle:BaseObject,
			bmd:DisplayObject):void
		{
			DrawAPI.drawRectWithBitMapFill(spriteGraphics,rectStyle,bmd);
		}
		
		/**
		 * 绘制矩形 
		 * @param spriteGraphics	：待绘制目标。
		 * @param rectStyle			：用于定义矩形样式，可由
		 * newx.com.utils.draw.DrawStyle生成。
		 * @param fillStyle			：背景填充类型，该值可由
		 * newx.com.utils.draw.DrawStyle生成。
		 * @param lineStyle			：线条类型，该值可由
		 * newx.com.utils.draw.DrawStyle生成。
		 * @param lineGradientStyle	：线条渐变类型，该值可由
		 * newx.com.utils.draw.DrawStyle生成。
		 * 
		 */
		public function DrawApi_DrawRect(
			spriteGraphics:Graphics,
			rectStyle:BaseObject,
			fillStyle:BaseObject,
			lineStyle:BaseObject=null,
			lineGradientStyle:BaseObject=null):void
		{
			DrawAPI.drawRect(
				spriteGraphics,rectStyle,fillStyle,lineStyle,lineGradientStyle);
		}
		
		/**
		 * 绘制圆角矩形 
		 * @param spriteGraphics	：待绘制目标。
		 * @param rectStyle			：用于定义矩形样式，可由
		 * newx.com.utils.draw.DrawStyle生成。
		 * @param fillStyle			：背景填充类型，该值可由
		 * newx.com.utils.draw.DrawStyle生成。
		 * @param lineStyle			：线条类型，该值可由
		 * newx.com.utils.draw.DrawStyle生成。
		 * @param lineGradientStyle	：线条渐变类型，该值可由
		 * newx.com.utils.draw.DrawStyle生成。
		 */
		public function DrawApi_DrawRoundRect(
			spriteGraphics:Graphics,
			rectStyle:BaseObject,
			fillStyle:BaseObject,
			lineStyle:BaseObject=null,
			lineGradientStyle:BaseObject=null):void
		{
			DrawAPI.drawRoundRect(
				spriteGraphics,rectStyle,fillStyle,lineStyle,lineGradientStyle);
		}
		
		//IO=========================================================
		/**
		 * 在Flex控制台上输出字符串，并加上输出时间,支持空格输出，逗号输出
		 * @param argc
		 * 
		 */
		public function IO_Traceln(...argc):void
		{
			IO.io.traceln(argc);
		}
		
		/**
		 * 在控制面板上输出字符串（格式：黑色），
		 * 并加上输出时间,支持空格输出，逗号输出
		 * @param argc
		 * 
		 */
		public function IO_TraceMessage(...argc):void
		{
			IO.io.traceMessage(argc);
		}
		
		/**
		 * 在控制面板上输出字符串（格式：灰色斜体），
		 * 并加上输出时间,支持空格输出，逗号输出
		 * @param argc
		 * 
		 */
		public function IO_TraceLog(...argc):void
		{
			IO.io.traceLog(argc);
		}
		
		/**
		 * 在控制面板上输出字符串（格式：红色），
		 * 并加上输出时间,支持空格输出，逗号输出
		 * @param argc
		 * 
		 */
		public function IO_TraceError(...argc):void
		{
			IO.io.traceError(argc);
		}
		
		//Utils(工具)================================================
		
		/**
		 * 百分比格式化.用于进度类的计算
		 * @param current		：当前量
		 * @param total			：总量
		 * @param precision		：精度.默认值100.可选;
		 * @return 
		 * 
		 */
		public function Math_PercentFormart(current:uint, total:uint, precision:uint=100):uint
		{
			return BMath.percentFormart(current,total,precision);
		}
		
		/**
		 * 以四舍五入的方式随机一个整数
		 * @param min	：最小值
		 * @param max	：最大值
		 * @return
		 * 
		 */
		public function Math_RandRangeFloor(min:Number, max:Number):int
		{
			return BMath.randRangeFloor(min,max);
		}
		
		/**
		 * 随机一个Number型整数
		 * @param min		：最小值
		 * @param max		：最大值
		 * @param length	：小数点位数
		 * @return 
		 * 
		 */
		public function Math_RandRangeNumber(min:Number, max:Number, length:uint=2):Number
		{
			return BMath.randRangeNumber(min,max);
		}
		
		/**
		 * 随机一个Int型整数
		 * @param min		：最小值
		 * @param max		：最大值
		 * @return 
		 * 
		 */
		public function Math_RandRangeInt(min:Number, max:Number):int
		{
			return BMath.randRangeInt(min,max);
		}
		
		/**
		 * DateFormat 格式化Date
		 * @param o       ：要格式化的Date对象实例
		 * @param format  ：格式化模板，支持
		 * "YYYY YY MMMM MMM MM M DD D EEEE EEE EE E A L HH:NN:SS XX(毫秒)"
		 * 【可选】，默认值:"YYYY-MM-DD HH:NN:SS".
		 */
		public function Format_Date(o:Date, format:String="YYYY-MM-DD HH:NN:SS"):String
		{
			return DateFormatter.DateFormat(o,format);
		}
		
		/**
		 * 格式化秒数.适合格式化播放器时间等
		 * @param second     ：要格式化的秒数
		 * @param showHours  ：当小于1小时时是否现实小时数.默认true.可选
		 */
		public function Format_SecondFormat(second:int, showHours:Boolean=true):String
		{
			return DateFormatter.SecondFormart(second,showHours);
		}
		
		/**
		 * 新建组合键管理者
		 * @param command		：键组
		 * @param stage			：用于监听的显示对象
		 * @param callBackFunc	：触发回调函数
		 * @param timeout		：键间隔（毫秒）
		 * @return 
		 * 
		 */
		public function Utils_KeyCommand(
			command:Array,
			stage:Stage,
			callBackFunc:Function,
			timeout:Number=2000):void
		{
			new KeyCommand(command,stage,callBackFunc,timeout);
		}
		
		/**
		 * 生成MD5编码
		 * @param s	：待生成的字符串。
		 * @return 
		 * 
		 */
		public function Utils_MD5(s:String):String
		{
			return MD5.hash(s);
		}
		
		public function MouseHandle_SetDrag(
			target:DisplayObject,
			isCopy:Boolean=true,
			data:Object=null):void
		{
			MouseHandle.getInstance().setDrag(target,isCopy,data);
		}
		
		/**
		 * 设置拖动 
		 * @param target	：设置拖动的显示对象
		 * @param isCopy	：是否从目标拷贝拖动对象
		 * @param data		：拖动随时传递的参数
		 * 
		 */
		public function MouseHandle_RemoveDrag():void
		{
			MouseHandle.getInstance().removeDrag();
		}
		
		/**
		 * 停止拖动 
		 * 
		 */
		public function get MouseHandle_TargetData():Object
		{
			return MouseHandle.getInstance().targetData;
		}
		
		/**
		 * 获取随拖动一起的参数 
		 * @return 
		 * 
		 */
		public function get MouseHandle_view():DisplayObject
		{
			return MouseHandle.getInstance().view;
		}

		//资源管理============================================================
		/**
		 * 根据资源类型复制出新的副本，主要用于复制图片，也可以复制经过处理
		 * 的swf文件。
		 * @param val	：被缓存的资源编号。
		 * @return 资源副本。
		 * 
		 */
		public function Res_Copy(val:Object):DisplayObject
		{
			return ResManager.copy(val);
		}

		/**
		 * 获取一个已经被加载过，并且被缓存的资源的一个副本，他不删除缓存的资源
		 * 而是根据资源类型复制出新的副本，主要用于复制图片，也可以复制经过处理
		 * 的swf文件。 
		 * @param key	：被缓存的资源编号。
		 * @return 	资源副本。
		 * 
		 */	
		public function Res_GetCopy(key:String):DisplayObject
		{
			return ResManager.getResContentCopy(key);
		}

		/**
		 * 加载一系列资源
		 * @param listArr			：一个结构为"{key:String,url:String}"的价值列表。
		 * @param onLoadComplete	：列表加载完成后的回调
		 * @param thisObj			：指定函数体内 thisObject 值的对象。
		 * @param onItemFun			：某一个对象加载完成的回调
		 * 
		 */
		public function Res_LoadList(
			listArr			:Array,
			onLoadComplete	:Function 	= null,
			thisObj			:Object 	= null,
			onItemFun		:Function 	= null):void
		{
			ResManager.loadResList(listArr,onLoadComplete,thisObj,onItemFun);
		}

		/**
		 * 加载并缓存资源
		 * @param key				：被缓存的资源编号。
		 * @param resPath			：资源加载地址
		 * @param onLoadComplete	：资源加载成功后的回调
		 * @param thisObj			：指定函数体内 thisObject 值的对象。
		 */
		public function Res_Load(
			key				:String,
			resPath			:String,
			onLoadComplete	:Function 	= null,
			pList			:Array 		= null):void
		{
			ResManager.loadRes(key,resPath,onLoadComplete,pList);
		}
		
		/**
		 * 加载资源，且不保存原始应用。
		 * 它同loadRes可以解决当多个加载需求为同一地址时只需要加载一遍。
		 * 不过它不保存原始引用，也就是说，当加载完成后，它不会将原始引用保存在内存中。
		 * @param key				：被缓存的资源编号。
		 * @param resPath			：资源加载地址
		 * @param onLoadComplete	：资源加载成功后的回调
		 * @param thisObj			：指定函数体内 thisObject 值的对象。
		 * 
		 */
		public static function Res_LoadNoSave(
			key				:String,
			resPath			:String,
			onLoadComplete	:Function = null,
			pList			:Array = null):void
		{
			ResManager.loadResNoSave(key,resPath,onLoadComplete,pList);
		}
		
		/**
		 * 通过new Class() 的方式，创建一个资源类。 
		 * @param className	：资源的绑定类名。
		 * @return 	资源类实例。
		 * 
		 */
		public function Res_NewClass(className:String):DisplayObject
		{
			return ResManager.newResClass(className);
		}
		
		/**
		 * 判断资源是否缓存，true时为已经缓存。
		 * @param key
		 * @return 
		 * 
		 */
		public function Res_IsResHave(key:String):Boolean
		{
			return ResManager.isResHave(key);
		}
		
		/**
		 * 删除资源缓存
		 * @param key	:被缓存的资源编号。
		 * 
		 */
		public function Res_DeleteRes(key:String):void
		{
			ResManager.deleteRes(key);
		}
		
		/**
		 * 清空Res管理器。 
		 * 
		 */		
		public function Res_ClearAllRes():void
		{
			ResManager.clearAllRes();
		}
		
		//tips管理器。
		/**
		 * 显示提示信息
		 * @param content		信息内容
		 * @param followMouse	是否跟随鼠标，如果不跟随鼠标，则必须设置stagePosition参数
		 * @param stagePosition	全局（舞台）坐标点  (此参数只在followMouse设置为false的时候才有效)
		 * 
		 */
		public function UI_ShowTips(
			content			:String,
			followMouse		:Boolean 	= true,
			stagePosition	:Point 		= null):void
		{
			NxToolTips.ShowInfo(content,followMouse,stagePosition);
		}
		
		public function UI_HideTips():void
		{
			NxToolTips.hide();
		}
	}
}